package org.report4service.services;

import javax.microedition.rms.RecordComparator;
import javax.microedition.rms.RecordEnumeration;
import javax.microedition.rms.RecordStoreException;
import javax.microedition.rms.RecordStoreNotOpenException;
import org.report4service.dbutils.RMSStorage;
import org.report4service.model.Report;
import org.report4service.utils.ReportParser;
import org.report4service.utils.Serializer;

/**
 * Implements adding hours, minutes,books,brochures etc for a particular report
 * for a specific day in a month
 * 0
 * @author Jmpango
 * 
 */
public class ReportServiceImpl extends RMSStorage {

    private ReportParser reportParser = new ReportParser();
    private Serializer serializer;
    private static String dbName = "reportDB";

    /** Default constructor */
    public ReportServiceImpl() {
        rc = new SubComparator();
        serializer = new Serializer();
        setDbName(dbName);
        startDB();
    }

    public void startDB(){
        try {
            openDB(dbName);
        } catch (Exception ex) {
            ex.printStackTrace();
        }
    }

    public void shutDB(){
        try {
            closeDB();
        } catch (Exception ex) {
            ex.printStackTrace();
        } 
    }

    /**
     *
     *
     * @param newReport
     * @param qButton its 1 if save and 0 if its edit
     * @return
     */
    public boolean addReport(Report newReport, int qButton) {
        Report oldReport = recordExist(newReport);
        if (oldReport != null) {
            String oldReportRecord = reportParser.getReportString(oldReport);

            if(qButton == 1){
                 oldReport.setBook(oldReport.getBook() + newReport.getBook());
                 oldReport.setBrochures(oldReport.getBrochures() + newReport.getBrochures());
                 oldReport.setMagazines(oldReport.getMagazines() + newReport.getMagazines());
                 oldReport.setMinutes(oldReport.getMinutes() + newReport.getMinutes());
                 oldReport.setReturnVisits(oldReport.getReturnVisits() + newReport.getReturnVisits());
            }else{
                 oldReport.setBook(newReport.getBook());
                 oldReport.setBrochures(newReport.getBrochures());
                 oldReport.setMagazines(newReport.getMagazines());
                 oldReport.setMinutes(newReport.getMinutes());
                 oldReport.setReturnVisits(newReport.getReturnVisits());
            }
           
            String newReportRecord = reportParser.getReportString(oldReport);
            try {
                if (updateDbRecord(oldReportRecord, newReportRecord)) {
                    oldReport = null;
                    return true;
                } else {
                    return false;
                }
            } catch (Exception ex) {
                eventListener.errorOccured("errors:", ex);
            } 

        } else {
            try {
                addDbRecord(reportParser.getReportString(newReport));
                oldReport = null;
            } catch (Exception ex) {
               eventListener.errorOccured("errors:", ex);
            }
        }

        return true;
    }

    public Report getReport(String date) {
        Report newReport = new Report();
        newReport.setDate(date);
        Report oldReport = recordExist(newReport);
        if (oldReport != null) {
            return oldReport;
        }
        return new Report();
    }

    /**
     * gets user from the enumerated records
     *
     * @param user
     * @return
     * @throws RecordStoreNotOpenException
     */
    private Report recordExist(Report report) {
        Report oldReport = new Report();
        try {
            int index = 0;
            RecordEnumeration recordEnumeration = enumerateRecords();
            while (recordEnumeration.hasNextElement()) {
                oldReport = serializer.deserialise(recordEnumeration.nextRecord(), ++index, getNumRecords());
                if (oldReport.getDate() == null) {
                    return null;
                }

                if (oldReport.getDate().equals(report.getDate())) {
                    return oldReport;
                }
            }
        } catch (Exception ex) {
            eventListener.errorOccured("errors:", ex);
        }
        return null;
    }

    public static String getDbName() {
        return dbName;
    }

    public static void setDbName(String dbName) {
        ReportServiceImpl.dbName = dbName;
    }

    

    /** Compare two records */
    private class SubComparator implements RecordComparator {

        public int compare(byte[] rec1, byte[] rec2) {
            try {
                String oldReportRecord = new String(rec1);
                String newReportRecord = new String(rec2);

                Report oldReport = reportParser.getReport(oldReportRecord);
                Report newReport = reportParser.getReport(newReportRecord);

                int result = oldReport.getDate().compareTo(newReport.getDate());
                if (result == 0) {
                    return RecordComparator.EQUIVALENT;
                } else if (result < 0) {
                    return RecordComparator.PRECEDES;
                } else {
                    return RecordComparator.FOLLOWS;
                }
            } catch (Exception e) {
                return RecordComparator.EQUIVALENT;
            }
        }
    }
}
